package com.whfc.common.face.wo;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.whfc.common.face.wotu.*;
import com.whfc.common.util.HttpUtil;
import com.whfc.common.util.MD5Util;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.MessageFormat;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Description wo平台API
 * @Author hw
 * @Date 2021/1/21 14:47
 * @Version 1.0
 */
public class WoFaceApi {

    private static final Logger logger = LoggerFactory.getLogger(WoFaceApi.class);

    private static final Integer SUCCESS_CODE = 1;

    /**
     * 应用appid
     */
    private String appId;

    /**
     * 应用key
     */
    private String appKey;

    /**
     * 应用secret
     */
    private String appSecret;

    public WoFaceApi(String appId, String appKey, String appSecret) {
        this.appId = appId;
        this.appKey = appKey;
        this.appSecret = appSecret;
    }

    /**
     * 鉴权获取token
     *
     * @return
     */
    public String auth() {
        String timestamp = String.valueOf(System.currentTimeMillis());
        String sign = sign(timestamp, appKey, appSecret);
        Map<String, String> param = new HashMap<>();
        param.put("appId", appId);
        param.put("appKey", appKey);
        param.put("timestamp", timestamp);
        param.put("sign", sign);
        String respond = HttpUtil.doGet(MessageFormat.format(WoApiConst.SERVER + WotuApiConst.AUTH_URL, appId), param, null);
        logger.info("WotuFaceApi.auth,response:{}", respond);
        WotuApiResult<String> result = JSONObject.parseObject(respond, new TypeReference<WotuApiResult<String>>() {
        });
        if (SUCCESS_CODE.equals(result.getResult())) {
            return result.getData();
        }
        return null;
    }

    /**
     * 添加设备
     *
     * @param deviceKey
     * @param name
     * @param tag
     * @param recType   1-云端识别，2-本地识别 根据设备的实际使用场景进行选择，现场人数小于设备容量，建议选本地识别；现场人数大于设备容量，选择云端识别
     * @return
     */
    public WotuApiResult<WotuApiAddDeviceResult> deviceCreate(String deviceKey, String name, String tag, String recType, String token) {
        logger.info("woApi添加设备:deviceKey:{},name:{},tag:{}", deviceKey, name, tag);

        Map<String, String> headers = new HashMap<>();
        headers.put("token", token);
        headers.put("Content-Type", "application/json");
        JSONObject param = new JSONObject();
        param.put("name", name);
        param.put("tag", tag);
        String url = MessageFormat.format(WoApiConst.SERVER + WoApiConst.ADD_DEVICE_URL, appId, deviceKey, 1);
        String respond = HttpUtil.doPost(url, param.toJSONString(), headers);
        WotuApiResult<WotuApiAddDeviceResult> result = JSON.parseObject(respond, new TypeReference<WotuApiResult<WotuApiAddDeviceResult>>() {
        });

        logger.info("添加设备url:{},respond:{},entity:{}", url, respond, result.toString());
        return result;
    }

    /**
     * 删除设备
     *
     * @param deviceKey
     * @return
     */
    public WotuApiResult deviceDel(String deviceKey, String token) {
        logger.info("woApi删除设备:deviceKey:{}", deviceKey);
        Map<String, String> headers = new HashMap<>();
        headers.put("token", token);
        String respond = HttpUtil.doDelete(WoApiConst.SERVER, MessageFormat.format(WoApiConst.DEL_DEVICE_URL, appId, deviceKey), null, headers);
        WotuApiResult result = JSON.parseObject(respond, WotuApiResult.class);
        logger.info("删除设备respond:{},entity:{}", respond, result.toString());
        return result;
    }

    /**
     * 添加人员
     *
     * @param name
     * @param phone
     * @return
     */
    public WotuApiResult<WotuApiAddPersonResult> personCreate(String name, String phone, String token) {
        logger.info("woApi添加人员:name:{},phone:{}", name, phone);
        Map<String, String> headers = new HashMap<>();
        headers.put("token", token);
        headers.put("Content-Type", "application/json");
        JSONObject param = new JSONObject();
        param.put("name", name);
        param.put("phone", phone);
        String respond = HttpUtil.doPost(MessageFormat.format(WoApiConst.SERVER + WoApiConst.ADD_PERSON_URL, appId), param.toJSONString(), headers);
        WotuApiResult<WotuApiAddPersonResult> result = JSON.parseObject(respond, new TypeReference<WotuApiResult<WotuApiAddPersonResult>>() {
        });
        logger.info("添加人员respond:{},entity:{}", respond, result.toString());
        return result;
    }

    /**
     * 人员删除
     *
     * @param personGuid
     * @param token
     */
    public WotuApiResult personDelete(String personGuid, String token) {
        return personDelete(Arrays.asList(personGuid), token);
    }

    /**
     * 人员批量删除
     *
     * @param personGuids
     * @param token
     */
    public WotuApiResult personDelete(List<String> personGuids, String token) {
        logger.info("woApi删除人员,personGuids:{}", personGuids);
        Map<String, String> headers = new HashMap<>();
        headers.put("token", token);
        headers.put("Content-Type", "application/json");
        Map<String, String> params = new HashMap<>();
        params.put("personGuids", StringUtils.join(personGuids, ","));
        String respond = HttpUtil.doDelete(WoApiConst.SERVER, MessageFormat.format(WoApiConst.DEL_PERSON_URL, appId), params, headers);
        WotuApiResult result = JSON.parseObject(respond, WotuApiResult.class);
        logger.info("woApi删除人员,respond:{},entity:{}", respond, result.toString());
        return result;
    }

    /**
     * 查询人员
     *
     * @param personGuid
     * @return
     */
    public WotuApiResult<WotuApiAddPersonResult> personFind(String personGuid, String token) {
        logger.info("woApi查询人员:personGuid:{}", personGuid);
        Map<String, String> headers = new HashMap<>();
        headers.put("token", token);
        headers.put("Content-Type", "application/json");
        String respond = HttpUtil.doGet(MessageFormat.format(WoApiConst.SERVER + WoApiConst.FIND_PERSON_URL, appId, personGuid), headers, null);
        WotuApiResult<WotuApiAddPersonResult> result = JSON.parseObject(respond, new TypeReference<WotuApiResult<WotuApiAddPersonResult>>() {
        });
        logger.info("查询人员respond:{},entity:{}", respond, result.toString());
        return result;
    }

    /**
     * 添加人员照片
     *
     * @param personGuid
     * @param imageUrl
     * @return
     */
    public WotuApiResult<WotuApiAddFaceImgResult> faceImgCreate(String personGuid, String imageUrl, String token) {
        logger.info("woApi添加人员照片:personGuid:{},imageUrl:{}", personGuid, imageUrl);
        Map<String, String> headers = new HashMap<>();
        headers.put("token", token);
        headers.put("Content-Type", "application/json");
        JSONObject param = new JSONObject();
        param.put("personGuid", personGuid);
        param.put("url", imageUrl);
        String respond = HttpUtil.doPost(MessageFormat.format(WoApiConst.SERVER + WoApiConst.ADD_PERSON_FACE_URL, appId), param.toJSONString(), headers);
        WotuApiResult<WotuApiAddFaceImgResult> result = JSON.parseObject(respond, new TypeReference<WotuApiResult<WotuApiAddFaceImgResult>>() {
        });
        logger.info("添加人员照片respond:{},entity:{}", respond, result.toString());
        return result;
    }

    /**
     * 闸机授权人员
     *
     * @param deviceKey
     * @param personGuid
     * @param type       1-本地 2-云端 授权本地人像库，调用设备授权人员接口后，设备会自动进行同步，云端将新增人员的数据信息同步至设备，同步需要一定时间。若设备在线，则立刻则进入同步状态；若设备离线，则联网后自动进行进入同步状态
     *                   授权云端人像库，立即成功
     * @return
     */
    public WotuApiResult setPeople(String deviceKey, String personGuid, String type, String token) {
        logger.info("woApi闸机授权人员:deviceKey:{},personGuid:{}", deviceKey, personGuid);
        Map<String, String> headers = new HashMap<>();
        headers.put("token", token);
        headers.put("Content-Type", "application/json");
        String respond = HttpUtil.doPut(WoApiConst.SERVER, MessageFormat.format(WoApiConst.ADD_SET_PEOPLE_URL, appId, deviceKey, personGuid, type), null, headers);
        WotuApiResult result = JSON.parseObject(respond, WotuApiResult.class);
        logger.info("闸机授权人员respond:{},entity:{}", respond, result.toString());
        return result;
    }

    /**
     * 闸机注销人员
     *
     * @param deviceKey
     * @param personGuid
     * @param type       1:本地库 2:云端库 销权本地人像库人员，若设备在线，则人员信息从设备删除，销权成功；若设备离线，则联网后自动进行人员信息删除和销权
     * @return
     */
    public WotuApiResult deleteSomePeople(String deviceKey, String personGuid, String type, String token) {
        logger.info("woApi闸机注销人员:deviceKey:{},personGuid:{}", deviceKey, personGuid);
        Map<String, String> headers = new HashMap<>();
        headers.put("token", token);
        headers.put("Content-Type", "application/json");
        String respond = HttpUtil.doDelete(WoApiConst.SERVER, MessageFormat.format(WoApiConst.ADD_DELETE_PEOPLE_URL, appId, deviceKey, personGuid, type), null, headers);
        WotuApiResult result = JSON.parseObject(respond, WotuApiResult.class);
        logger.info("闸机注销人员respond:{},entity:{}", respond, result.toString());
        return result;
    }

    /**
     * 闸机开门
     *
     * @param deviceKey
     * @param token
     * @return
     */
    public WotuApiResult interactive(String deviceKey, String token) {
        logger.info("woApi闸机开门:deviceKey:{}", deviceKey);
        Map<String, String> headers = new HashMap<>();
        headers.put("token", token);
        headers.put("Content-Type", "application/json");
        JSONObject json = new JSONObject();
        json.put("type", 1);
        String respond = HttpUtil.doPost(WoApiConst.SERVER + MessageFormat.format(WoApiConst.INTER_ACTIVE_RL, appId, deviceKey), json.toJSONString(), headers);
        WotuApiResult result = JSON.parseObject(respond, WotuApiResult.class);
        logger.info("woApi闸机开门respond:{},entity:{}", respond, result.toString());
        logger.info("woApi闸机开门code:{}", result.getCode());
        return result;
    }

    /**
     * 签名
     *
     * @param timestamp
     * @return
     */
    private static String sign(String timestamp, String appKey, String appSecret) {
        String md5 = MD5Util.md5Encode(new StringBuffer(appKey).append(timestamp).append(appSecret).toString());
        logger.info("md5:[{}]", md5);
        return md5;
    }

}
